﻿#include <CommonHelper.h>
#include <QDebug>

CommonHelper::CommonHelper()
{

}


CommonHelper& CommonHelper::Common()
{
    static CommonHelper instance;
    return instance;
}

/**
 * @brief CommonHelper::GetGuid 获取GUID
 * @return
 */
QString CommonHelper::GetGuid(){
    QUuid id = QUuid::createUuid();
    QString strGuid =id.toString(QUuid::Id128);
    return  strGuid;
}

/**
 * @brief CommonHelper::GetDateTimeStr 获取时间戳 2025-03-31 08:00:00
 * @return
 */
QString CommonHelper::GetDateTimeStr(){
    QDateTime current=QDateTime::currentDateTime();
    QString dateStr=current.toString("yyyy-MM-dd hh:mm:ss");
    return dateStr;
}

/**
 * @brief CommonHelper::GetDateTimeStr 获取时间戳 2025-03-31 08:00:00
 * @return
 */
QString CommonHelper::GetTimeStr(){
    QDateTime current=QDateTime::currentDateTime();
    QString dateStr=current.toString("hh:mm:ss");
    return dateStr;
}

/**
 * @brief CommonHelper::TenToSixteen 十进制转十六进制
 * @param num
 * @param bit
 * @return
 */
QString CommonHelper::TenToSixteen(int num, int bit){
    QString hex = QString::number(num, 16);
    if (hex.length() < bit) {
        int n = bit - hex.length();
        for (int i = 0; i < n; i++) {
            hex.prepend("0");
        }
    }

    QString result;
    for (int i = 0; i < hex.length(); ++i) {
        result.append(hex.at(i).toUpper());
        if (i % 2 == 1 && i != hex.length() - 1) {
            result.append(" ");
        }
    }
    return result;
}

/**
 * @brief CommonHelper::binaryToHex 2进制转16进制
 * @param data  参数 例:11111111
 * @return
 */
QString CommonHelper::binaryToHex(const QString &data) {
    bool ok;
    int val = data.toInt(&ok,2);
    QString m_strHex = QString("%1").arg(val,2,16,QLatin1Char('0')).toUpper();
    return m_strHex;
}

/**
 * @brief CommonHelper::GetSendData 获取发送指令
 * @param sendData
 * @return
 */
QByteArray CommonHelper::GetSendData(QString sendData){
    sendData= sendData.trimmed();
    QByteArray result;
    for(int i = 0;i<sendData.size();i++)
    {
        if(sendData[i]==' ')
            continue;   //跳过
        int num  = sendData.mid(i,2).toUInt(nullptr,16);
        i++;
        result.append(num);
    }
    return result;
}

/**
 * @brief CommonHelper::GetCrcCheck 获取校验位
 * @param data
 * @return
 */
QString CommonHelper::GetCrcCheck(QString data) {
    QByteArray dataArray = hexStringToByteArray(data);

    int len=dataArray.size();
    uint16_t wcrc=0XFFFF;//预置16位crc寄存器，初值全部为1
    uint8_t temp;//定义中间变量
    int i=0,j=0;//定义计数
    for(i=0;i<len;i++)//循环计算每个数据
    {
        temp=dataArray.at(i);
        wcrc^=temp;
        for(j=0;j<8;j++){
            //判断右移出的是不是1，如果是1则与多项式进行异或。z
            if(wcrc&0X0001){
                wcrc>>=1;//先将数据右移一位
                wcrc^=0XA001;//与上面的多项式进行异或
            }
            else//如果不是1，则直接移出
                wcrc>>=1;//直接移出
        }
    }
    return TenToSixteen(uint8_t(wcrc>>8),1)+" "+TenToSixteen(uint8_t(wcrc),1);
}

/**
 * @brief CommonHelper::SixteenToTen 十六进制转十进制
 * @param data
 * @return
 */
QString CommonHelper::SixteenToTen(QString data){
    data.replace(" ","");
    bool ok;
    int dec = data.toInt(&ok,16);
    QString num = QString("%1").arg(dec,0,10);
    return  num;
}

/**
 * @brief CommonHelper::SixteenToTwo 十六进制转二进制
 * @param data
 * @return
 */
QString CommonHelper::SixteenToTwo(QString data){
    QString bin = QString::number(data.toInt(NULL, 16), 2);
    return bin;
}

/**
 * @brief CommonHelper::hexToBinFormatted 十六进制转2进制
 * @param hexStr
 * @return
 */
QString CommonHelper::hexToBinFormatted(QString hexStr)
{
    QString binStr;

    // 将每个十六进制字符转换为4位二进制字符串
    for (const QChar &c : hexStr) {
        bool ok;
        int value = QString(c).toInt(&ok, 16);
        if (!ok) {
            return QString(); // 处理非法字符，返回空字符串或根据需求处理
        }
        binStr += QString("%1").arg(value, 4, 2, QChar('0')); // 4位二进制，左侧补零
    }

    // 补足到8的倍数长度（在前面补零）
    int length = binStr.length();
    if (length % 8 != 0) {
        int pad = 8 - (length % 8);
        binStr.prepend(QString(pad, '0'));
    }

    // 分割为每两位并用空格连接
    QStringList list;
    for (int i = 0; i < binStr.length(); i += 2) {
        list << binStr.mid(i, 2);
    }

    return list.join(" ");
}

/**
 * @brief CommonHelper::binToDecFormatted 二进制转10进制
 * @param binStr
 * @return
 */
QString CommonHelper::binToDecFormatted(QString binStr) {
    QStringList binParts = binStr.split(' ', Qt::SkipEmptyParts); // 按空格分割
    QStringList decParts;

    for (const QString &part : binParts) {
        // 检查是否为两位二进制
        if (!part.contains(QRegularExpression("^[01]+$"))) {
            return QString(); // 非法输入返回空
        }
        bool ok;
        int decimal = part.toInt(&ok, 2); // 二进制转十进制
        if (!ok) return QString();
        decParts.append(QString::number(decimal)); // 转为字符串
    }

    return decParts.join(" "); // 用空格连接结果
}

/**
 * @brief CommonHelper::hexStringToByteArray 16进制转数组
 * @param HexString
 * @return
 */
QByteArray CommonHelper::hexStringToByteArray(QString HexString)
{
    bool ok;
    QByteArray ret;
    HexString = HexString.trimmed();
    HexString = HexString.simplified();
    QStringList sl = HexString.split(" ");

    foreach (QString s, sl)
    {
        if(!s.isEmpty())
        {
            char c = static_cast<char>(s.toInt(&ok, 16) & 0xFF);
            if(ok)
            {
                ret.append(c);
            }
            else
            {
                qDebug()<<"error:"<<s;

            }
        }
    }

    return ret;
}

/**
 * @brief CommonHelper::getItemCode 获取字典代码
 * @param id
 * @param name
 * @return
 */
QString CommonHelper::getItemCode(QString id,QString name){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select num From Deftab Where id='%1' and value='%2'").arg(id,name);
    query.exec(sql);
    QString result;
    while (query.next()) {
        result= query.value("num").toString();
    }
    return  result;
}

/**
 * @brief CommonHelper::getItemName 获取字典名称
 * @param id
 * @param code
 * @return
 */
QString CommonHelper::getItemName(QString id,QString code)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select value From Deftab Where id='%1' and num='%2'").arg(id,code);
    query.exec(sql);
    QString result;
    while (query.next()) {
        result= query.value("value").toString();
    }
    return  result;
}

/**
 * @brief CommonHelper::minToSecond 单位转换 分钟转秒
 * @param min
 * @param diameter
 * @return
 */
QString CommonHelper::minToSecond(QString min,QString diameter)
{
    double r=diameter.toDouble()/2;
    double round=3.1415*r*r;
    double result=min.toDouble()*1000/(60*round);
    return QString::number(result,'f',6);
}

/**
 * @brief CommonHelper::secondToMin 单位转换 秒转成分钟
 * @param sec
 * @param diameter
 * @return
 */
QString CommonHelper::secondToMin(QString sec,QString diameter)
{
    double r=diameter.toDouble()/2;
    double round=3.1415*r*r;
    double result=(60*round*sec.toDouble())/1000;
    return QString::number(result,'f',6);
}

/**
 * @brief CommonHelper::minToSecond 单位转换 分钟转秒
 * @param min
 * @param diameter
 * @return
 */
double CommonHelper::minToSecond(double min,double diameter)
{
    double r=diameter/2;
    double round = 3.1415 * r * r;
    double result = min * 1000 / (60*round);
    return result;
}

/**
 * @brief CommonHelper::secondToMin 单位转换 秒转分钟
 * @param sec
 * @param diameter
 * @return
 */
double CommonHelper::secondToMin(double sec,double diameter)
{
    double r = diameter / 2;
    double round = 3.1415 * r * r;
    double result = (60 * round * sec) / 1000;
    return result;
}

/**
 * @brief CommonHelper::getErrorInfo 获取故障信息
 * @param errorCode
 * @return
 */
QStringList CommonHelper::getErrorInfo(QString errorCode)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Module,ErrorName,ErrorMethod,IsBlocked From FaultInformation Where ErrorCode='%1'").arg(errorCode);
    query.exec(sql);
    QStringList result;
    QString isBlocked;
    QString module;
    while (query.next()) {
        result.append(query.value("ErrorName").toString());
        result.append(query.value("ErrorMethod").toString());
        isBlocked=query.value("IsBlocked").toString();
    }
    if(isBlocked=="是"){
        result.clear();
    }
    return  result;
}

/**
 * @brief CommonHelper::isCurrentModuleError 校验是否 是当前模块故障
 * @param errorCode
 * @return
 */
bool CommonHelper::isCurrentModuleError(QString errorCode){
    //    if(StaticProperties::currentExpType==0){
    //        return true;
    //    }
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Module,ErrorName,ErrorMethod,IsBlocked From FaultInformation Where ErrorCode='%1'").arg(errorCode);
    query.exec(sql);
    QString module;
    while (query.next()) {
        module=query.value("Module").toString();
    }
    if(StaticProperties::isConcurrency && module.contains("4")){
        return true;
    }
    else
    {
        return  module.contains(QString::number(StaticProperties::currentExpModule));
    }
    return false;
}

int CommonHelper::getErrorType(QString errorCode){

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Module,ErrorName,ErrorMethod,IsBlocked From FaultInformation Where ErrorCode='%1'").arg(errorCode);
    query.exec(sql);
    QString module;
    while (query.next()) {
        module=query.value("Module").toString();
    }
    if(StaticProperties::isConcurrency && module.contains("4")){
        return 1;
    }else{
        return 0;
    }
}

/**
 * @brief CommonHelper::getCurrentExpTypeCode 模块转换
 * @param name
 * @return
 */
int CommonHelper::getCurrentExpTypeCode(QString name){
    if(name=="全流程"){
        return 0;
    }
    else if(name=="放靶"){
        return 1;
    }
    else if(name=="打靶"){
        return 2;
    }
    else if(name=="转靶"){
        return 3;
    }
    else if(name=="纯化"){
        return 4;
    }
    else
    {
        return -1;
    }
}

/**
 * @brief CommonHelper::getCurrentExpTypeCode 模块转换
 * @param name
 * @return
 */
QString CommonHelper::getCurrentExpTypeName(int code){
    switch (code) {
    case 0:
        return "全流程";
    case 1:
        return "放靶";
    case 2:
        return "打靶";
    case 3:
        return "转靶";
    case 4:
        return "纯化";
    default:
        return "";
    }
}

// 非阻塞延时函数（在事件循环中等待）
void CommonHelper::nonBlockingDelay(int milliseconds) {
    QEventLoop loop;
    QTimer timer;
    timer.setSingleShot(true);
    QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
    timer.start(milliseconds);
    loop.exec(); // 进入事件循环，但允许处理其他事件
}

/**
 * @brief CommonHelper::setDefaultDetectionParameters 设置默认检测信息
 */
void CommonHelper::setDefaultDetectionParameters(){
    //放靶检测
    //0 靶材罐有无  1传靶气泵压力 2挡板
    StaticProperties::releasseTargetStatus=
    {
        {"0","--"},
        {"1","--"},
        {"2","--"}
    };

    //打靶检测
    //0 靶材罐有无检测 1气泵压力 2送靶气缸 3进料气缸 4水冷机
    StaticProperties::practiceTargetStatus=
    {
        {"0","--"},
        {"1","--"},
        {"2","--"},
        {"3","--"},
        {"4","--"}
    };

    //转靶检测
    //0 吸盘状态 1夹爪 2靶材盖 3液位 4溶靶瓶 5靶材片吸取
    StaticProperties::shiftingTargetStatus=
    {
        {"0","--"},
        {"1","--"},
        {"2","--"},
        {"3","--"},
        {"4","--"},
        {"5","--"}
    };

    //纯化检测
    //0 左压紧 1右压紧 2耗材触点 3废液瓶有无 4产物瓶有无 5能谱图检测
    StaticProperties::purifyingStatus=
    {
        {"0","--"},
        {"1","--"},
        {"2","--"},
        {"3","--"},
        {"4","--"},
        {"5","--"}
    };

    //管道状态检测
    //-1 未知状态 0正常状态 1第一次经过 2第二次经过 3故障 4屏蔽
    StaticProperties::pipeStatus=
    {
        {"0",-1},
        {"1",-1},
        {"2",-1},
        {"3",-1},
        {"4",-1}
    };
}

/**
 * @brief CommonHelper::staticUseTime 统计使用时间
 * @param type
 * @param time
 */
void CommonHelper::staticUseTime(int type,QString time)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString info;
    QDateTime current=QDateTime::currentDateTime();
    QString dateStr=current.toString("yyyy-MM-dd");
    switch (type) {
    case 1:
        info=QString("ExperimentalRunningTime = (ExperimentalRunningTime*3600.0+%1)/3600.0").arg(time);
        break;
    case 2:
        info=QString("TargetPeristalticPump = (TargetPeristalticPump*3600.0+%1)/3600.0").arg(time);
        break;
    case 3:
        info=QString("PurifyingPeristalticPump = (PurifyingPeristalticPump*3600.0+%1)/3600.0").arg(time);
        break;
    case 4:
        info=QString("CompressRubberPadTimes=CompressRubberPadTimes+%1").arg(time);
        break;
    case 5:
        info=QString("VacuumSuctionCupUseTime=VacuumSuctionCupUseTime+%1").arg(time);
        break;
    case 6:
        info=QString("ClawUsageDuration=(ClawUsageDuration*3600.0+%1)/3600.0").arg(time);
        break;
    case 7:
        info=QString("ExpansionClipUseTime=ExpansionClipUseTime+%1").arg(time);
    }
    QString sql=QString("Update DataStatistics Set %1 Where StaticDate='%2'").arg(info,dateStr);
    query.exec(sql);

}

/**
 * @brief CommonHelper::ShieldingDetection 屏蔽检测
 * @param serial
 * @return
 */
bool CommonHelper::ShieldingDetection(int serial)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select IsBlocked From DetectorInformation Where serial='%1'").arg(QString::number(serial));
    query.exec(sql);
    while (query.next()) {
        return query.value("IsBlocked")=="是";
    }
}

/**
 * @brief CommonHelper::getSendDataLength 获取长度
 * @param info
 * @return
 */
QString CommonHelper::getSendDataLength(QString info){
    QStringList list=info.split(" ");
    int len= list.length()+4;
    return TenToSixteen(len,2);
}
